﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Resources;
using System.IO;
using PokeData;

namespace PokeTD_MapEditor {
    public partial class TilesetEditor : Form {
        public TilesetEditor(TilesetDS tds, Image[] tileset, byte[,] map) {
            InitializeComponent();
            _tileset = tileset;
            for (int i = 0; i < tileset.Length; i++) {
                PictureBox pb = new PictureBox();
                pb.SizeMode = PictureBoxSizeMode.StretchImage;
                pb.Height = 32;
                pb.Width = 32;
                pb.Click += new EventHandler(pb_Click);
                pb.Image = tileset[i];
                pnlTileset.Controls.Add(pb);
            }
            this.tds = tds;
            this._map = map;
        }

        private TilesetDS tds;
        private Image[] _tileset;
        private byte[,] _map;

        public Image[] Tileset {
            get { return _tileset; }
        }
        public byte[,] Map {
            get { return _map; }
        }

        private PictureBox selectedPb = new PictureBox();

        private void TilesetEditor_Load(object sender, EventArgs e) {

        }

        void pb_Click(object sender, EventArgs e) {
            grpTile.Enabled = true;
            if (selectedPb != null) selectedPb.BorderStyle = BorderStyle.None;
            selectedPb = (PictureBox)sender;
            selectedPb.BorderStyle = BorderStyle.FixedSingle;
            pbTile.Image = selectedPb.Image;
            chkBegehbar.Checked = tds.Tile[pnlTileset.Controls.IndexOf(selectedPb)].isWalkable;
        }

        private void TilesetEditor_FormClosing(object sender, FormClosingEventArgs e) {
            if (pnlTileset.Controls.Count == 0) {
                if (MessageBox.Show("Das Tileset enthält keine Tiles. Tileset-Editor trotzdem schließen?", "Tileset-Editor", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) {
                    e.Cancel = true;
                }
            }
        }

        private void bttnNewTile_Click(object sender, EventArgs e) {
            NeuesTile ntile = new NeuesTile();
            if (pnlTileset.Controls.Count > 255) {
                MessageBox.Show("Eine Map darf maximal 256 verschiedene Tiles besitzen!", "Fehler");
                return;
            }
            if (ntile.ShowDialog() == DialogResult.OK) {
                Image img = Image.FromFile(ntile.FileName);
                img.Equals(img);
                addNewTile(img, ntile.Walkable, true);
            }
        }

        private void addNewTile(Image img, bool walkable, bool warnScale) {
            if (warnScale && (img.Width != 32 || img.Height != 32)) {
                if (MessageBox.Show("Achtung: Die gewählte Grafik wird auf 32x32 Pixel skaliert!", "Warnung", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel) {
                    return;
                }
            }
            tds.Tile.AddTileRow(_tileset.Length, walkable);
            Array.Resize<Image>(ref _tileset, _tileset.Length + 1);
            _tileset[_tileset.Length - 1] = img;
            
            PictureBox pb = new PictureBox();
            pb.SizeMode = PictureBoxSizeMode.StretchImage;
            pb.Height = 32;
            pb.Width = 32;
            pb.Click += new EventHandler(pb_Click);
            pb.Image = img;
            //chkBegehbar.Checked = ntile.Walkable;
            pnlTileset.Controls.Add(pb);
            pb_Click(pb, EventArgs.Empty);
        }
        private void bttnImport_Click(object sender, EventArgs e) {
            bool clearControls = false;
            if (pnlTileset.Controls.Count > 0 && MessageBox.Show("Aktuell geladenes Tileset entfernen?", "Tileset-Editor", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
                clearControls = true;
            }
            TilesetImport tsImport = new TilesetImport();
            
            if (tsImport.ShowDialog() == DialogResult.OK) {
                Image img = Image.FromFile(tsImport.FileName);
                int tileHeight = tsImport.TileHeight;
                int tileWidth = tsImport.TileWidth;
                int numTilesY = img.Height / tileHeight;
                int numTilesX = img.Width / tileWidth;
                int numTiles = numTilesX * numTilesY - (clearControls ? 0 : pnlTileset.Controls.Count);
                if (numTiles > 256) {
                    if (MessageBox.Show("Eine Map darf maximal 256 verschiedene Tiles besitzen. Das Importieren des gewählten Tilesets würde die Grenze überschreiten. Es werden daher maximal 256 Tiles importiert. Fortfahren?", "Tileset-Editor", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) {
                        return;
                    }
                }
                if (clearControls) pnlTileset.Controls.Clear();
                progressBar.Visible = true;
                progressBar.Maximum = Math.Min(numTiles, 200);
                //progressBar.PerformStep();
                for (int y = 0; y < numTilesY; y++) {
                    for (int x = 0; x < numTilesX; x++) {
                        Bitmap b = new Bitmap(tileWidth, tileHeight);
                        Graphics g = Graphics.FromImage(b);
                        g.DrawImage(img, new Rectangle(0, 0, b.Width, b.Height), tileWidth * x, tileHeight * y, b.Width, b.Height, GraphicsUnit.Pixel);
                        g.Dispose();
                        addNewTile(b, true, false);
                        progressBar.PerformStep();
                        progressBar.Refresh();
                        if (pnlTileset.Controls.Count == 256) {
                            progressBar.Visible = false;
                            progressBar.Value = 0;
                            return;
                        }
                    }
                }
                progressBar.Visible = false;
                progressBar.Value = 0;
                
            }
        }

        private void chkBegehbar_CheckedChanged(object sender, EventArgs e) {
            tds.Tile[pnlTileset.Controls.IndexOf(selectedPb)].isWalkable = chkBegehbar.Checked;
            tds.AcceptChanges();
        }

        private void btnÄndern_Click(object sender, EventArgs e) {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "PNG-Dateien|*.png";
            if (dlg.ShowDialog() == DialogResult.OK) {
                Image img = Image.FromFile(dlg.FileName);
                if (img.Width != 32 || img.Height != 32) {
                    if (MessageBox.Show("Die gewählte Grafik ist nicht 32x32 Pixel groß. Soll die Grafik auf 32x32 Pixel skaliert werden?", "Warnung", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
                        Bitmap b = new Bitmap(img, 32, 32);
                        img = b;
                    } else {
                        return;
                    }
                }

                _tileset[pnlTileset.Controls.IndexOf(selectedPb)] = img;
                selectedPb.Image = img;
                pbTile.Image = img;
            }
        }

        private void btnLöschen_Click(object sender, EventArgs e) {
            int index = pnlTileset.Controls.IndexOf(selectedPb);
            int height = _map.GetLength(0);
            int width = _map.GetLength(1);
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    if (_map[y, x] == index) {
                        _map[y, x] = 0;
                    } else if (_map[y, x] > index) {
                        _map[y, x]--;
                    }
                }
            }
            for (int i = index; i < tds.Tile.Count; i++) {
                tds.Tile[i].id--;
            }
            if (index + 1 < _tileset.Length) {
                Array.Copy(_tileset, index + 1, _tileset, index, _tileset.Length - index-1);
            }
            Array.Resize<Image>(ref _tileset, _tileset.Length - 1);
            pnlTileset.Controls.Remove(selectedPb);
            tds.Tile.RemoveTileRow(tds.Tile[index]);
            tds.AcceptChanges();
            pbTile.Image = null;
            grpTile.Enabled = false;
        }

    }
}
